const axios = require("axios").default.create({
  headers: {
    "User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36 OPR/52.0.2871.40"
  }
});
const get = require("get");
const path = require("path");
const url = require("url");
const util = require("util");


/**
 * @description 也有很长的 https://wetransfer.com/downloads/17d7bd567542ac1c2729489152a964ee20180914123853/3252233245c0012381fb313137030c1c20180914123853/dfce2d
 * @param {String} we_link 可能形如https://wetransfer.com/downloads/4cfb4db3f537f77b40d7c49be4b055d020180915004835/39a32f,也可能形如https://we.tl/t-eGnWPAcUU7 
 * @param {String} dist_dir path for download dir,must exist
 * @returns {Promise<{ok:Boolean,msg:String,file_full_path:String}>}
 */
function downloadWeTrasfer(we_link, dist_dir) {
  return new Promise(async resolve => {
    let parsed = url.parse(we_link);
    if (parsed.hostname == "we.tl") {
      axios.get(we_link, { maxRedirects: 0, validateStatus: s => s == 302 }).then(async axresp => {
        let headers = axresp.headers;
        if (headers['location']) {
          let o_ = await downloadWeTrasfer(headers['location'], dist_dir);
          resolve({
            ok: o_.ok,
            msg: o_.msg,
            file_full_path: o_.file_full_path
          })
        } else {
          resolve({
            ok: false,
            msg: "没有返回location字段",
            file_full_path: ""
          })
        }
      }).catch(async axerr => {
        if (axerr.response) {
          resolve({
            ok: false,
            msg: `HTTP ${axerr.response.status + axerr.response.statusText};${util.inspect(axerr.response.data)}`,
            file_full_path: ""
          })
        } else {
          resolve({
            ok: false,
            msg: axerr.message,
            file_full_path: ""
          })
        }

      })
    } else if (parsed.hostname == "wetransfer.com") {
      let o_parsedWelink = await prepareParseWetransferUrl(we_link);
      if (!o_parsedWelink.ok) {
        return resolve({
          ok: false,
          msg: `failed in prepareParseWetransferUrl():${o_parsedWelink.msg}`
        })
      }
      let matched = parsed.pathname.match(/\/downloads(\/[0-9a-z]+)(\/[0-9a-z]+)(\/[0-9a-z]+)*/);
      if (matched.length == 4) {
        let request;
        if (matched[3]) {
          //属于比较长的
          let api_link = `https://wetransfer.com/api/v4/transfers/${matched[1]}/download`;
          request = axios.post(api_link, {
            security_hash: matched[3].replace("/", ""),
            recipient_id: matched[2].replace("/", "")
          }, {
            headers: {
              "Content-Type": "application/json",
              "Accept": "application/json",
              "x-csrf-token": o_parsedWelink.data.csrf_token,
              cookie: `_wt_session=${o_parsedWelink.data.wt_session}`
            },
            validateStatus: s => s == 200
          }
          )
        } else {
          //属于短一点的
          let api_link = `https://wetransfer.com/api/v4/transfers/${matched[1]}/download`;
          request = axios.post(api_link, {
            security_hash: matched[2].replace("/", ""),
            // domain_user_id: "8deccc05-e93b-4c10-8692-4cb00f44ec2b"
          }, {
            headers: {
              "Content-Type": "application/json",
              "Accept": "application/json",
              "x-csrf-token": o_parsedWelink.data.csrf_token,
              cookie: `_wt_session=${o_parsedWelink.data.wt_session}`
            },
            validateStatus: s => s == 200
          }
          )
        }


        request.then(async axresp => {
          let direct_link = axresp.data['direct_link'];
          let parsed_direct_link = url.parse(direct_link);
          let file_name = path.basename(parsed_direct_link.pathname);
          get(direct_link).toDisk(path.join(dist_dir, file_name), async (err, file_path) => {
            if (err) {
              resolve({
                ok: false,
                msg: `download get() 失败:${err}`,
                file_full_path: ""
              })
            } else {
              resolve({
                ok: true,
                msg: "ok",
                file_full_path: file_path || path.join(dist_dir, file_name)
              })
            }
          })
        }).catch(async axerr => {
          if (axerr.response) {
            resolve({
              ok: false,
              msg: `HTTP ${axerr.response.status + axerr.response.statusText};${util.inspect(axerr.response.data)}`,
              file_full_path: ""
            })
          } else {
            resolve({
              ok: false,
              msg: axerr.message,
              file_full_path: ""
            })
          }
        })
      } else {
        resolve({
          ok: false,
          msg: `链接长得有毛病:${we_link}`,
          file_full_path: ""
        })
      }
    } else {
      resolve({
        ok: false,
        msg: "链接不是wetransfer.com或者we.tl域名",
        file_full_path: ""
      })
    }
  })
}


/**
 * @returns {Promise<{ok:Boolean,msg:String,data:{csrf_token:String,wt_session:string}}>}
 * @param {String} we_link 
 */
function prepareParseWetransferUrl(we_link) {
  return new Promise(async resolve => {
    axios.get(we_link, {
      headers: {
        'cache-control': 'max-age=0',
        'sec-fetch-mode': 'navigate',
        'sec-fetch-site': 'none',
        'sec-fetch-user': '?1'
      },
      validateStatus: s => s == 200
    }).then(axresp => {
      if (!(axresp.headers["set-cookie"]
        && util.isArray(axresp.headers["set-cookie"])
        && axresp.headers["set-cookie"].length == 1
        && axresp.headers["set-cookie"][0].includes("_wt_session")
      )) {
        return resolve({
          ok: false,
          msg: `can't find wt_session in headers:headers["set-cookie"] is ${util.inspect(axresp.headers["set-cookie"])}`
        })
      }
      /**@type {string} */
      let setWtSessionStr = axresp.headers["set-cookie"][0];
      let session_matched = setWtSessionStr.match(/_wt_session=([^;]*);/);
      if (!(session_matched && session_matched.length == 2)) {
        return resolve({
          ok: false,
          msg: `can't extract wt_session from ${setWtSessionStr}`
        })
      }
      /**@type {string} */
      let _wt_session = session_matched[1];
      /**
       * @type {string}
       */
      let htmlText = axresp.data;
      let splited = htmlText.split("\n").filter(e => e.includes("csrf-token"));
      if (!splited.length == 1) {
        return resolve({
          ok: false,
          msg: `unlegal csrf-token?${util.inspect(splited)}`
        })
      }
      htmlText = splited[0]

      /**
       * @description <meta name="csrf-token" content="d7Tq897YFavrM9q+vo7U8HOtVpZb8D4OGDccEIfIx4zmeHRR2wzmX5oYcoYrilbRr8VxGi+C51xQXe+Q5Km8rQ==" />
       */
      let csrfMatched = htmlText.match(/<meta(\s)+name="csrf-token"(\s)+content="([^"]*)"/);
      if (!(csrfMatched && csrfMatched.length == 4)) {
        return resolve({
          ok: false,
          msg: `unlegal csrf-token?${util.inspect(htmlText)}`
        })
      }
      let csrf_token = csrfMatched[3];
      return resolve({
        ok: true,
        msg: "ok",
        data: {
          wt_session: _wt_session,
          csrf_token: csrf_token
        }
      })
      debugger
    }).catch(axerr => {
      if (axerr.response) {
        resolve({
          ok: false,
          msg: `HTTP ${axerr.response.status + axerr.response.statusText};${util.inspect(axerr.response.data)}`,
          data: {}
        })
      } else {
        resolve({
          ok: false,
          msg: axerr.message,
          data: {}
        })
      }
    })
  })
}

module.exports = {
  downloadWeTrasfer: downloadWeTrasfer,
  __debug: {
    prepareParseWetransferUrl
  }
}
